class Sound 
{
  String src;
  SoundManager mgr;
  DOM.AudioBufferSourceNode audioBufferSourceNode;
  String _state;
  bool _startPLayingAfterReady = false;
  
  Sound(String this.src)
  {
    mgr = new SoundManager();    
    
    DOM.ArrayBuffer buffer = mgr.getBuffer(src);
    
    if(buffer != null)
    {
      decodeBuffer(buffer);
    }
    else
    {
      _state =  "LOADING";
      XMLLoader loader = new XMLLoader(this.src, onSoundLoaded);
    }
  }
  
  String get state() => _state;
  
  void onSoundLoaded(DOM.ArrayBuffer buffer)
  {
    mgr.addBuffer(src, buffer);
    decodeBuffer(buffer);
  }
  
  void decodeBuffer(DOM.ArrayBuffer buffer)
  {
    mgr.context.decodeAudioData(buffer, onSoundDecodeSuccess, onSoundDecodeFail);
  }
  
  bool onSoundDecodeSuccess(DOM.AudioBuffer buffer)
  {
    setBuffer(buffer);
  }
  
  bool onSoundDecodeFail(DOM.AudioBuffer buffer)
  {
    _state = "FAILED";
    print('failed to decode buffer');
  }
  
  void setBuffer(DOM.AudioBuffer buffer)
  { 
    _state = "READY";
    
    this.audioBufferSourceNode = mgr.context.createBufferSource(); 
    audioBufferSourceNode.buffer = buffer;                    
    audioBufferSourceNode.connect(mgr.context.destination,0,0);
    
    if(_startPLayingAfterReady)
    {
      audioBufferSourceNode.noteOn(0);
      _startPLayingAfterReady = false;
    }
  }
  
  void play()
  {
    if(state == "READY")
    {
      audioBufferSourceNode.noteOn(0);
    }
    else _startPLayingAfterReady = true;
  }
  
}
